package com.mzm.util.persistency;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.LockOptions;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import dnl.toolbox.api.PaginationInfo;

/**
 * 
 * @author Daniel Orr
 */
public class GenericDaoImpl<T, ID extends Serializable> extends HibernateDaoSupport implements
		GenericDao<T, ID> {

	private Class<?> persistentClass;

	public GenericDaoImpl(Class<?> persistentClass) {
		this.persistentClass = persistentClass;
	}

	private Class<?> getPersistentClass() {
		return persistentClass;
	}

	public void setPersistentClass(Class<?> persistentClass) {
		this.persistentClass = persistentClass;
	}

	@Override
	@SuppressWarnings( { "unchecked" })
	public T findById(ID id, boolean lock) throws DataAccessException {
		return (T) getSession()
				.load(getPersistentClass(), id, (lock) ? LockOptions.UPGRADE : LockOptions.NONE);
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<T> findByExample(T exampleInstance) throws DataAccessException {
		return findByCriteria(Example.create(exampleInstance));
	}

	@SuppressWarnings( { "unchecked" })
	public T store(T entity) throws DataAccessException {
		return (T) getSession().merge(entity);
	}

	@Override
	public void delete(T entity) throws DataAccessException {
		getSession().delete(entity);
	}

	@Override
	@SuppressWarnings( { "unchecked" })
	public List findAll() throws DataAccessException {
		return findByCriteria();
	}

	@SuppressWarnings( { "unchecked" })
	protected List findByCriteria(Criterion... criterion) {
		Criteria criteria = getSession().createCriteria(getPersistentClass());
		for (Criterion c : criterion) {
			criteria.add(c);
		}
		return criteria.list();
	}

	@SuppressWarnings("unchecked")
	@Override
	public ID create(T entity) {
		return (ID) getHibernateTemplate().save(entity);
	}

	@Override
	public void createOrUpdate(T entity) {
		getHibernateTemplate().saveOrUpdate(entity);
	}

	@Override
	public void delete(ID id) {
		Object obj = findById(id, false);
		getHibernateTemplate().delete(obj);
	}

	@Override
	public void deleteAll() {
		throw new UnsupportedOperationException();
	}

	@Override
	public T findUniqueResultByExample(T example) {
		throw new UnsupportedOperationException();
	}

	@Override
	public Collection<T> getPage(PaginationInfo paginationInfo) {
		throw new UnsupportedOperationException();
	}

	@Override
	public int getTotalNumberOfEntities() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void merge(T entity) {
		getHibernateTemplate().merge(entity);
	}

	@Override
	public void refresh(T entity) {
		getHibernateTemplate().refresh(entity);
	}

	@Override
	public void update(T entity) {
		getHibernateTemplate().update(entity);
	}

	@Override
	public long count() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public List<T> find(String queryString, Object... values) {
		return null;
	}

}